package user

import (
	"context"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"
	user2 "git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/repository/user"
	pb "git.mycaigou.com/gfyx/micro-gfyx-user-service/proto/micro_gfyx_user_service_proto/micro-gfyx-user-service"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/service/user"
	"git.myscrm.cn/golang/common/ykerrcode"
	"time"
)

type UserLogin struct {
	userLoginService user.UserLoginServiceIface
	userInfoService  user.UserInfoServiceIface
}

func NewUserLogin(userLoginServiceIface user.UserLoginServiceIface,
	userInfoService user.UserInfoServiceIface) pb.UserLoginServiceServer {
	return &UserLogin{
		userLoginService: userLoginServiceIface,
		userInfoService:  userInfoService,
	}
}

func (u *UserLogin) UserApply(ctx context.Context, req *pb.UserApplyRequest) (*pb.UserApplyResponse, error) {
	var response = &pb.UserApplyResponse{}
	if req.GetMobile() == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "手机号为空")
	}

	userApply := &user2.CommonUserApply{
		Mobile:    req.GetMobile(),
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
		IsDeleted: 0,
	}

	_, err := u.userInfoService.SaveUserApply(ctx, userApply)
	if err != nil {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, err.Error())
	}

	response.IsSuccess = true
	return response, nil
}

func (u *UserLogin) BindUser(ctx context.Context, request *pb.BindUserRequest) (*pb.LoginResponse, error) {
	var response = &pb.LoginResponse{}
	if request.Type != 1 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "暂时只支持小程序绑定")
	}
	if request.Openid == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "openid不能为空")
	}
	if request.Mobile == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "mobile不能为空")
	}
	commonUserInfoBo, token, err := u.userLoginService.BindUser(ctx, request.Mobile, request.Openid, request.Type, request.UnionId)
	if err != nil {
		return response, err
	}
	if token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "token生成失败")
	}
	response.Token = token
	userInfo := &pb.LoginUserInfo{
		UserId:      commonUserInfoBo.TenantUserId,
		UserName:    commonUserInfoBo.UserName,
		UserUid:     commonUserInfoBo.TenantUserUid,
		MpOpenId:    commonUserInfoBo.MpOpenid,
		Uid:         commonUserInfoBo.Uid,
		UserCode:    commonUserInfoBo.UserCode,
		MobilePhone: commonUserInfoBo.MobilePhone,
		MpUnionId:   commonUserInfoBo.MpUnionId,
	}
	response.UserInfo = userInfo
	// 租户为空的是个人用户
	if commonUserInfoBo.TenantCode != "" {
		tenantProfitUse, err := u.userInfoService.GetTenantProfitUse(ctx, commonUserInfoBo.TenantCode)
		if err != nil {
			return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "获取租户权益失败")
		}
		tenantInfo := &pb.TenantInfoFromLogin{
			TenantCode: commonUserInfoBo.TenantCode,
			TenantName: commonUserInfoBo.TenantName,
			// 租户线索雷达权益
			ClueRadarPayStatus: tenantProfitUse.ClueRadarPayStatus,
		}
		tenantInfoList := make([]*pb.TenantInfoFromLogin, 0)
		tenantInfoList = append(tenantInfoList, tenantInfo)
		response.TenantInfo = tenantInfoList
	}

	return response, nil
}

func (u *UserLogin) LoginByOpenId(ctx context.Context, request *pb.LoginByOpenIdRequest) (*pb.LoginResponse, error) {
	var response = &pb.LoginResponse{}
	if request.Type != 1 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "暂时只支持小程序登录")
	}
	if request.Openid == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "openid不能为空")
	}
	commonUserInfoBo, token, err := u.userLoginService.LoginByOpenId(ctx, request.Openid, request.Type, request.UnionId)
	if err != nil {
		return response, err
	}
	if token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "token生成失败")
	}
	response.Token = token
	userInfo := &pb.LoginUserInfo{
		UserId:      commonUserInfoBo.TenantUserId,
		UserName:    commonUserInfoBo.UserName,
		UserUid:     commonUserInfoBo.TenantUserUid,
		MpOpenId:    commonUserInfoBo.MpOpenid,
		Uid:         commonUserInfoBo.Uid,
		UserCode:    commonUserInfoBo.UserCode,
		MobilePhone: commonUserInfoBo.MobilePhone,
		MpUnionId:   commonUserInfoBo.MpUnionId,
	}
	response.UserInfo = userInfo
	// 租户为空的是个人用户
	if commonUserInfoBo.TenantCode != "" {
		tenantProfitUse, err := u.userInfoService.GetTenantProfitUse(ctx, commonUserInfoBo.TenantCode)
		if err != nil {
			return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "获取租户权益失败")
		}
		tenantInfo := &pb.TenantInfoFromLogin{
			TenantCode:         commonUserInfoBo.TenantCode,
			TenantName:         commonUserInfoBo.TenantName,
			ClueRadarPayStatus: tenantProfitUse.ClueRadarPayStatus,
		}
		tenantInfoList := make([]*pb.TenantInfoFromLogin, 0)
		tenantInfoList = append(tenantInfoList, tenantInfo)
		response.TenantInfo = tenantInfoList
	}
	return response, nil
}

func (u *UserLogin) VerifyToken(ctx context.Context, request *pb.VerifyTokenRequest) (*pb.VerifyTokenResponse, error) {
	response := &pb.VerifyTokenResponse{}
	if request.Token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "token不能为空")
	}
	commonUserInfoBo, err := u.userLoginService.VerifyToken(ctx, request.Token)
	if err != nil {
		return response, err
	}
	userInfo := &pb.LoginUserInfo{
		UserId:      commonUserInfoBo.TenantUserId,
		UserName:    commonUserInfoBo.UserName,
		UserUid:     commonUserInfoBo.TenantUserUid,
		MpOpenId:    commonUserInfoBo.MpOpenid,
		Uid:         commonUserInfoBo.Uid,
		UserCode:    commonUserInfoBo.UserCode,
		MobilePhone: commonUserInfoBo.MobilePhone,
		MpUnionId:   commonUserInfoBo.MpUnionId,
	}
	response.UserInfo = userInfo
	// 租户为空的是个人用户
	if commonUserInfoBo.TenantCode != "" {
		tenantProfitUse, err := u.userInfoService.GetTenantProfitUse(ctx, commonUserInfoBo.TenantCode)
		if err != nil {
			return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "获取租户权益失败")
		}
		tenantInfo := &pb.TenantInfoFromLogin{
			TenantCode: commonUserInfoBo.TenantCode,
			TenantName: commonUserInfoBo.TenantName,
			// 租户线索雷达权益
			ClueRadarPayStatus: tenantProfitUse.ClueRadarPayStatus,
		}
		tenantInfoList := make([]*pb.TenantInfoFromLogin, 0)
		tenantInfoList = append(tenantInfoList, tenantInfo)
		response.TenantInfo = tenantInfoList
	}

	return response, nil

}

// 通过账号密码登录
func (u *UserLogin) LoginByAccountPassword(ctx context.Context, request *pb.LoginByAccountPasswordRequest) (*pb.LoginByAccountPasswordResponse, error) {
	var response = &pb.LoginByAccountPasswordResponse{}
	if request.TenantCode == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "租户编码不能为空")
	}
	if request.Account == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "账号不能为空")
	}
	if request.Password == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "密码不能为空")
	}

	commonUserInfoBo, token, err := u.userLoginService.LoginByAccountPassword(ctx, request.TenantCode, request.Account, request.Password, true)
	if err != nil {
		return response, err
	}
	if token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "token生成失败")
	}
	response.Token = token
	userInfo := &pb.LoginUserInfo{
		UserId:      commonUserInfoBo.TenantUserId,
		UserName:    commonUserInfoBo.UserName,
		UserUid:     commonUserInfoBo.TenantUserUid,
		Uid:         commonUserInfoBo.Uid,
		UserCode:    commonUserInfoBo.UserCode,
		MobilePhone: commonUserInfoBo.MobilePhone,
		MpUnionId:   commonUserInfoBo.MpUnionId,
	}
	response.UserInfo = userInfo
	// 获取接口租户名称
	tenantName, err := u.userInfoService.GetTenantName(ctx, commonUserInfoBo.TenantCode, false)
	if err != nil {
		return response, err
	}
	commonUserInfoBo.TenantName = tenantName
	tenantInfo := &pb.TenantInfoFromLogin{
		TenantCode: commonUserInfoBo.TenantCode,
		TenantName: commonUserInfoBo.TenantName,
	}
	tenantInfoList := make([]*pb.TenantInfoFromLogin, 0)
	tenantInfoList = append(tenantInfoList, tenantInfo)
	response.TenantInfo = tenantInfoList
	return response, nil
}

// 退出登录
func (u *UserLogin) Logout(ctx context.Context, request *pb.LogoutRequest) (*pb.LogoutResponse, error) {
	var response = &pb.LogoutResponse{}
	if request.Token != "" {
		err := u.userLoginService.LogoutByToken(ctx, request.Token)
		if err != nil {
			return response, err
		}
	} else {
		if request.LogoutType == "" {
			return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "退登类型不能为空")
		}
		if request.GlobalUserId == "" {
			return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "账号不能为空")
		}
		err := u.userLoginService.Logout(ctx, request.GlobalUserId, request.LogoutType)
		if err != nil {
			return response, err
		}
	}
	return response, nil
}

// 通过sso登录
func (u *UserLogin) LoginBySso(ctx context.Context, request *pb.LoginBySsoRequest) (*pb.LoginBySsoResponse, error) {
	var response = &pb.LoginBySsoResponse{}
	if request.AccessToken == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "access_token不能为空")
	}
	//signingKey := stark.Configer.(stark.ApolloConfigerIface).GetStringValue("gfyx_model_main_key", "")
	//todo 不同应用使用不同key来解析
	mainAppClaims, err := utils.DefaultJWT.ParseMainAppToken(request.AccessToken, utils.DEFAULT_SINGKEY)
	if err != nil {
		return response, err
	}
	//登录
	tenantCode := mainAppClaims.T
	tenantUserCode := mainAppClaims.U
	appid := mainAppClaims.A
	if tenantCode == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少租户号")
	}
	if tenantUserCode == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少用户编码")
	}
	//未来用来区分登录来源
	if appid == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少应用id")
	}
	//获取是否存在登录记录，有则返回
	_, token, err := u.userLoginService.LoginBySso(ctx, tenantCode, tenantUserCode, appid)
	if err != nil {
		return response, err
	}
	if token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "token生成失败")
	}
	response.Token = token
	return response, nil
}

// 通过手机号+验证码登录
func (u *UserLogin) LoginByMobileSms(ctx context.Context, request *pb.LoginByMobileSmsRequest) (*pb.LoginByMobileSmsResponse, error) {
	var response = &pb.LoginByMobileSmsResponse{}
	if request.Mobile == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "手机号不能为空")
	}

	if request.SmsCode == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "验证码不能为空")
	}

	commonUserInfoBo, token, err := u.userLoginService.LoginByMobileSms(ctx, request, 1)
	if err != nil {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, err.Error())
	}
	if token == "" {
		return response, ykerrcode.TogRPCError(ykerrcode.FAIL, "token生成失败")
	}
	response.Token = token

	userInfo := &pb.LoginUserInfo{
		UserId:      commonUserInfoBo.TenantUserId,
		UserName:    commonUserInfoBo.UserName,
		UserUid:     commonUserInfoBo.TenantUserUid,
		Uid:         commonUserInfoBo.Uid,
		UserCode:    commonUserInfoBo.UserCode,
		MobilePhone: commonUserInfoBo.MobilePhone,
		MpUnionId:   commonUserInfoBo.MpUnionId,
	}
	response.UserInfo = userInfo
	if commonUserInfoBo.TenantCode != "" {
		// 获取接口租户名称
		tenantProfitUse, err := u.userInfoService.GetTenantProfitUse(ctx, commonUserInfoBo.TenantCode)
		if err != nil {
			return response, err
		}
		tenantName, err := u.userInfoService.GetTenantName(ctx, commonUserInfoBo.TenantCode, false)
		if err != nil {
			return response, err
		}
		commonUserInfoBo.TenantName = tenantName
		tenantInfo := &pb.TenantInfoFromLogin{
			TenantCode:         commonUserInfoBo.TenantCode,
			TenantName:         commonUserInfoBo.TenantName,
			ClueRadarPayStatus: tenantProfitUse.ClueRadarPayStatus,
		}
		tenantInfoList := make([]*pb.TenantInfoFromLogin, 0)
		tenantInfoList = append(tenantInfoList, tenantInfo)
		response.TenantInfo = tenantInfoList
	}

	return response, nil
}
